/*
 * @Description:
 * @Author: Cxy
 * @Date: 2024-02-15 11:18:50
 * @LastEditors: Cxy
 * @LastEditTime: 2024-09-05 13:55:26
 * @FilePath: \xy-admin\play\vite.proxy.ts
 */

import type { ProxyOptions } from 'vite'

/* 常规类型 */
interface ProxyItemInter {
  // 代理标识符
  key: string
  // 别名 与接口映射
  keyAlias?: string
  // 源地址
  target: string
  // 类型 server 普通服务器  socket socket服务器
  type: 'server' | 'socket'
  //
  rewrite?: (path: string) => string
}

/* 特殊类型 第一个必须存在一个默认代理且无别名，也就是除了特定的接口其他接口都会走这个代理 */
type ProxyDefaultItemInter = ProxyItemInter & { defaultProxyIdentifier: true; keyAlias?: never }

type proxyInter = {
  [key in string]: [ProxyDefaultItemInter, ...ProxyItemInter[]]
}

/**
 * @description: 此处可同时配置开发及生产代理，供调试
 */
export const proxy: proxyInter = {
  development: [
    /* 常规服务器 */
    // 默认代理: http://localhost:5173/a -> http://localhost:3000/a
    {
      key: '/defaultApi',
      target: 'http://localhost:3000',
      type: 'server',
      defaultProxyIdentifier: true
    },
    // 别名代理: http://localhost:5173/aliasApi/alias/a -> http://localhost:3001/alias/a
    {
      key: '/aliasApi',
      target: 'http://localhost:3001',
      type: 'server',
      keyAlias: '/alias' // 别名: 只要是以 /alias/ 为开头的请求，前面会加上 /aliasApi 来代理到 http://localhost:3001/
    },
    // 无别名代理: http://localhost:5173/noAliasApi/a -> http://localhost:3002/a
    {
      key: '/noAliasApi',
      target: 'http://localhost:3002',
      type: 'server',
      rewrite: path => path
    },
    // 不重置path: http://localhost:5173/notResetPathApi/a -> http://localhost:3003/notResetPathApi/a
    {
      key: '/notResetPathApi',
      target: 'http://localhost:3003',
      type: 'server',
      rewrite: path => path
    },
    /* websockets 或 socket.io */
    { key: '/apiNext', target: 'ws://localhost:5174', type: 'socket' }
  ]
  // production: []
}

export default (mode: string) => {
  return proxy[mode]?.reduce((prev: Record<string, string | ProxyOptions>, { key, target, type, rewrite }) => {
    // https://cn.vitejs.dev/config/server-options.html#server-proxy
    prev[key] =
      type === 'server'
        ? {
            target,
            changeOrigin: true,
            rewrite: (path: string) => (rewrite ? rewrite(path) : path.replace(new RegExp(`^\\${key}`), ''))
          }
        : {
            target,
            ws: true
          }
    return prev
  }, {})
}
